﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using Citi.Pearl.SchedulerUI.EmailSenderWcf;
using Citi.RoutineBase;

namespace Citi.Pearl.SchedulerUI
{
    public class EmailFinished : IExecutableRoutine
    {
        public IEnumerable<RoutineParameter> Parameters
        {
            get
            {
                return new List<RoutineParameter> { 
                    new RoutineParameter{ Description = "CRC Report Path", Name ="CRCReportPath", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "PEARL Report Path", Name ="PEARLReportPath", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "CRC Control File", Name ="CRCControlFile", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "PEARL Control File", Name ="PEARLControlFile", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Email to send when some error occurs. Separated by Semicolons(;).", Name ="EmailAddressError", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Users that must receive email when the reports are available. Separated by Semicolons(;).", Name ="EmailAddressUsers", Nullable= false, Required = true, Type = typeof(string)},
                    new RoutineParameter{ Description = "Email Sender Template Id", Name ="EmailTemplateId", Nullable= false, Required = true, Type = typeof(int)},
                    new RoutineParameter{ Description = "Email Control File", Name ="EmailControlFile", Nullable= false, Required = true, Type = typeof(string)}
                };
            }
        }

        public void Rollback(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }

        public void Start(DateTime scheduledDate, ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {
            var templateId = int.Parse(parameters["EmailTemplateId"].ToString());
            var crcReportPath = parameters["CRCReportPath"].ToString();
            var pearlReportPath = parameters["PEARLReportPath"].ToString();
            var crcControlFile = parameters["CRCControlFile"].ToString();
            var emailControlFile = parameters["EmailControlFile"].ToString();
            var pearlControlFile = parameters["PEARLControlFile"].ToString();
            var robotUsername = parameters["RobotUsername"].ToString();
            var robotPassword = parameters["RobotPassword"].ToString();
            var emailAddressUsers = parameters["EmailAddressUsers"].ToString().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries);
            var emailAddressError = parameters["EmailAddressError"].ToString().Split(new[] { ';' }, StringSplitOptions.RemoveEmptyEntries).ToList();

            if (ValidateFiles(crcControlFile, pearlControlFile, emailAddressError, robotUsername, robotPassword, ref currentAction, emailControlFile))
            {
                using (var client = new EmailClient())
                {
                    //using (new Impersonator(robotUsername.Split('\\').Last(), robotUsername.Split('\\').First(), robotPassword))
                    //{
                    var email = new EmailSenderWcf.Email
                    {
                        TemplateId = templateId,
                        Importance = EnumsEmailImportance.Normal,
                        To = emailAddressUsers.Select(x => new EmailSenderWcf.EmailAddress { Description = x }).ToList(),
                        Parameters = new Dictionary<string, string> 
                        { 
                            { "[Date]", DateTime.Today.ToString("dd/MM/yyyy") }, 
                            { "[LinkCRC]", crcReportPath } ,
                            { "[LinkPearl]", pearlReportPath },
                            { "[UpdatedDatePearl]", File.GetLastWriteTime(pearlControlFile).ToString("dd/MM/yyyy") },
                            { "[UpdateTimePearl]", File.GetLastWriteTime(pearlControlFile).ToString("HH:mm") },
                            { "[UpdatedDateCRC]", File.GetLastWriteTime(crcControlFile).ToString("dd/MM/yyyy") },
                            { "[UpdateTimeCRC]", File.GetLastWriteTime(crcControlFile).ToString("HH:mm") }
                        }
                    };

                    client.InsertEmailInQueue(email);
                    //}
                }
            }
        }

        private string GetErrorMessage(string reportPath)
        {
            var messageError = string.Format("Path: {0}", string.Concat(reportPath, " {0}"));

            if (!File.Exists(reportPath))
                return string.Format(messageError, "File doesn't exist");
            if (File.GetLastWriteTime(reportPath).Date != DateTime.Today)
                return string.Format(messageError, string.Format("File is out of date. Last Update: {0}", File.GetLastWriteTime(reportPath).Date));
            else
                return string.Format(messageError, "File OK");
        }

        public bool ValidateFiles(string crcReportPath, string pearlReportPath, List<string> emailAddressError, string username, string password, ref ICurrentAction currentAction, string emailControlFile)
        {
            currentAction.Description = "Validating files";

            if (File.Exists(emailControlFile) && File.GetLastWriteTime(emailControlFile).Date == DateTime.Today)
                return SendEmailAlreadySent(emailAddressError, emailControlFile);

            var invalid = !File.Exists(crcReportPath) || File.GetLastWriteTime(crcReportPath).Date != DateTime.Today
                || !File.Exists(pearlReportPath) || File.GetLastWriteTime(pearlReportPath).Date != DateTime.Today;

            if (!invalid)
            {
                currentAction.Description = "Validation is OK";
                File.Create(emailControlFile);
                return true;
            }

            var crcError = GetErrorMessage(crcReportPath);
            var pearlError = GetErrorMessage(pearlReportPath);

            currentAction.Description = "Validation failed. An error email will be sent.";
            currentAction.Description = string.Concat("CRC: ", crcError);
            currentAction.Description = string.Concat("PEARL: ", pearlError);

            using (var client = new EmailClient())
            {
                var email = new EmailSenderWcf.Email
                {
                    BodyMessage = string.Format("An error ocurred when this routine tried to send PEARL/CRC email<br/><br/> <b>CRC:</b> {0} <br/> <b>PEARL:</b> {1}",
                        crcError, pearlError),
                    Subject = "PEARL/CRC Error",
                    SentOnBehalfOfName = "O&T Finance Comunica",
                    To = emailAddressError.Select(x => new EmailSenderWcf.EmailAddress { Description = x }).ToList(),
                    ApplicationName = "General Automations",
                    Parameters = new Dictionary<string, string>(),
                    Importance = EnumsEmailImportance.High
                };

                client.InsertEmailInQueue(email);
            }

            return false;
        }

        private static bool SendEmailAlreadySent(List<string> emailAddressError, string emailControlFile)
        {
            using (var client = new EmailClient())
            {
                var email = new EmailSenderWcf.Email
                {
                    BodyMessage = string.Format("Email already sent to this execution. If you want to send this email again, please delete the file control({0})", emailControlFile),
                    Subject = "PEARL/CRC Error",
                    SentOnBehalfOfName = "O&T Finance Comunica",
                    To = emailAddressError.Select(x => new EmailSenderWcf.EmailAddress { Description = x }).ToList(),
                    ApplicationName = "General Automations",
                    Parameters = new Dictionary<string, string>(),
                    Importance = EnumsEmailImportance.High
                };

                client.InsertEmailInQueue(email);
            }

            return false;
        }

        public void Stop(ref ICurrentAction currentAction, Dictionary<string, object> parameters)
        {

        }
    }
}
